#include <FileSystem/FAT32.h>
#include <FileSystem/FileAPI.h>
#include <ProcessThread/ProcessThread.h>
#include <IntExcept/Error.h>
#include <Utility/CLib.h>

#define PATTERN_NOT_PREFIX (0)
#define PATTERN_IS_PREFIX (1)
#define EQUAL_STRING (2)

static DWORD TestPrefix(LPCSTR lpszString, LPCSTR lpszPattern)
{
    KERNEL_ASSERT(lpszString && lpszString[0], "Invalid string.\r\n");
    KERNEL_ASSERT(lpszPattern && lpszString[0], "Invalid string.\r\n");
    // if (strlen(lpszString) < strlen(lpszPattern))
    // {
    //     return PATTERN_NOT_PREFIX;
    // }
    DWORD dwResult = 0;
    DWORD j = 0;
    while (TRUE)
    {
        /* 只要模式串当前字符与主串当前字符相同，检查会一直进行 */
        if (lpszPattern[j] != '\0' && lpszPattern[j] == lpszString[j])
        {
            j++;
        }
        /* 当模式串当前字符为 '\0' 且主串当前字符非 '\0'，便意味着串已经匹配 */ 
        else if (lpszPattern[j] == '\0' && lpszString[j] != '\0')
        {
            return PATTERN_IS_PREFIX;
        }
        /* 特别地，主串和模式串当前字符相同且为 '\0'，说明字符串相等 */
        else if (lpszPattern[j] == '\0' && lpszString[j] == '\0')
        {
            return EQUAL_STRING;
        }
        else
        {
            return PATTERN_NOT_PREFIX;
        }
    }  
}

LPFileControlBlock MatchFCBByPath(LPCSTR lpszFileName)
{
    LPFileControlBlock lpMatch = &g_FCBCache; /* 所有的文件名都匹配根目录 */
    LPFileControlBlock lpTest = g_FCBCache.lpNext;
    DWORD dwTestResult = PATTERN_IS_PREFIX;
    /* 进行前缀匹配 */
    while (lpTest)
    {
        dwTestResult = TestPrefix(lpszFileName, lpTest->lpszPath);
        if (dwTestResult == EQUAL_STRING) /* 路径完全匹配 */
        {
            break;
        }
        else if (dwTestResult == PATTERN_IS_PREFIX) /* 前缀匹配 */
        {
            if (strlen(lpTest->lpszPath) > strlen(lpMatch->lpszPath)) /* 更长的匹配 */
            {
                lpMatch = lpTest; /* 更新匹配 */
            }
        }
        /* 继续探查是否存在更长的前缀匹配 */
        lpTest = lpTest->lpNext;
    }
    /* 检查匹配的 FCB 是否合法 */
    if (FCBIsDirectory(lpMatch) && dwTestResult == EQUAL_STRING)
    {
        lpMatch = NULL;
        SetLastError(ERROR_ACCESS_DENIED); /* 试图访问目录文件 */
    }
    else if (!FCBIsDirectory(lpMatch) && dwTestResult != EQUAL_STRING)
    {
        lpMatch = NULL;
        SetLastError(ERROR_PATH_NOT_FOUND); /* 把普通文件作为目录 */
    }
    SetLastError(ERROR_SUCCESS);
    return lpMatch;
}   